package com.siemens.industrial.web.mvc.service.admin;

import com.siemens.industrial.model.admin.Tenant;
import com.siemens.industrial.model.admin.TenantServiceRelation;
import com.siemens.industrial.model.admin.User;
import com.siemens.industrial.utils.GlobalResponseCode;
import com.siemens.industrial.utils.SiemensException;
import com.siemens.industrial.utils.SiemensFileReader;
import com.siemens.industrial.utils.UUIDGenerator;
import com.siemens.industrial.web.mvc.dao.admin.TenantDao;
import com.siemens.industrial.web.mvc.dao.admin.TenantServiceRelationDao;
import com.siemens.industrial.web.mvc.pojo.DataTableQuery;
import com.siemens.industrial.web.mvc.service.partner.PartnerUserService;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by qupen on 2016/8/31.
 */
@Service
public class TenantService {
    @Resource
    TenantDao tenantDao;

    @Resource
    PartnerUserService partnerUserService;

    @Resource
    TenantServiceRelationDao tenantServiceRelationDao;

    @Resource
    JdbcTemplate jdbcTemplate;

    /**
     * Tenant database schema template
     */
    private final static String tenantDatabaseTemplate = "/schema_tenant.sql";

    /**
     * Tenant database name label
     */
    private final static String tenantIdLabel = "\\{tenantId\\}";

    /**
     * Create tenant database
     *
     * @return tenantId
     */
    @Transactional
    public boolean save(Map<String, Object> data, String password) throws SiemensException {
        int o = 0, n = 0;
        if (data.containsKey("tenantName")) {
            String tenantName = data.get("tenantName").toString();
            Tenant tenantByName = tenantDao.getTenantByName(tenantName);
            Tenant tenantByKey = this.getTenantByKey(data.get("key").toString());
            if (tenantByName != null || tenantByKey != null) {
                throw new SiemensException(GlobalResponseCode.ERROR_TENANT_NOT_CREATE);
            }
            String tenantId = this.getTenantId();
            if (!tenantId.isEmpty()) {
                com.siemens.industrial.model.partner.User user = new com.siemens.industrial.model.partner.User();
                Tenant tenant = new Tenant();
                user.setUserId(tenantId);
                tenant.setTenantId(tenantId);
                user.setUserName("admin");
                user.setRoleId(0);
                user.setPassword(password);
                tenant.setTenantName(data.get("tenantName").toString());
                if (data.containsKey("telephone")) {
                    user.setTelephone(data.get("telephone").toString());
                    tenant.setTelephone(data.get("telephone").toString());
                }
                if (data.containsKey("logoMd5")) {
                    user.setLogoMd5(data.get("logoMd5").toString());
                    tenant.setLogoMd5(data.get("logoMd5").toString());
                }
                if (data.containsKey("address")) {
                    tenant.setAddress(data.get("address").toString());
                }
                if (data.containsKey("content")) {
                    user.setContact(data.get("content").toString());
                    tenant.setContact(data.get("content").toString());
                }
                if (data.containsKey("mail")) {
                    user.setEmail(data.get("mail").toString());
                    tenant.setManagerEmail(data.get("mail").toString());
                }
                if (data.containsKey("detail")) {
                    tenant.setDescription(data.get("detail").toString());
                }
                if (data.containsKey("key")) {
                    tenant.setTenantKey(data.get("key").toString());
                }
                tenant.setPassword(password);
                o = partnerUserService.saveUser(tenant.getTenantKey(), tenantId, user);//创建租户管理员
                n = tenantDao.save(tenant);//创建租户
                if (data.containsKey("service")) {
                    List<String> serviceIds = (List<String>) data.get("service");
                    for (int i = 0; i < serviceIds.size(); i++) {
                        TenantServiceRelation ts = new TenantServiceRelation();
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                        try {
                            ts.setStartDate(new java.sql.Date(format.parse(data.get("startTime").toString()).getTime()));
                            ts.setEndDate(new java.sql.Date(format.parse(data.get("endTime").toString()).getTime()));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }

                        ts.setServiceId(String.valueOf(serviceIds.get(i)));
                        ts.setTenantId(tenantId);
                        ts.setEnabled(1);
                        tenantServiceRelationDao.save(ts);// 创建该租户的服务
                    }
                }
            }
        }
        return (o == 1 && n == 1);
    }

    @Transactional
    private String getTenantId() throws SiemensException {
        String tenantId = UUIDGenerator.getUUID();
        String templateSql = SiemensFileReader.readToString(getClass().getResourceAsStream(tenantDatabaseTemplate));

        if (templateSql.equals("")) {
            throw new SiemensException(GlobalResponseCode.ERROR_FILE_NOT_FOUND);
        }
        //根据租户id创建数据库
        tenantDao.createTenantDatabase(templateSql.replaceAll(tenantIdLabel, tenantId));

        return tenantId;

    }

    @Transactional
    public int resetPassword(String password, String tenantId) throws SiemensException {
        Tenant tenant = this.getTenant(tenantId);
        partnerUserService.updateUserPwd(tenant.getTenantKey(), tenantId, tenantId, password);
        return tenantDao.initPassword(password, tenantId);
    }

    public List<Tenant> getTenantList() {
        return tenantDao.getTenants();
    }

    public Tenant getTenant(String tenantId) {
        return tenantDao.findOneById(tenantId);
    }

    public void updateTenant(Map<String, Object> data) throws SiemensException {
        if (data.containsKey("tenantId")) {
            Tenant tenant = this.getTenant(data.get("tenantId").toString());
            if (tenant != null) {
                if (data.containsKey("TenantName")) {
                    tenant.setTenantName(data.get("TenantName").toString());
                }
                if (data.containsKey("telephone")) {
                    tenant.setTelephone(data.get("telephone").toString());
                }
                if (data.containsKey("logoMd5")) {
                    tenant.setLogoMd5(data.get("logoMd5").toString());
                }
                if (data.containsKey("address")) {
                    tenant.setAddress(data.get("address").toString());
                }
                if (data.containsKey("content")) {
                    tenant.setContact(data.get("content").toString());
                }
                if (data.containsKey("mail")) {
                    tenant.setManagerEmail(data.get("mail").toString());
                }
                if (data.containsKey("detail")) {
                    tenant.setDescription(data.get("detail").toString());
                }
                tenantDao.updateById(tenant);
            }
        } else {
            throw new SiemensException(GlobalResponseCode.ERROR_STATE_EXISTED);
        }
    }

    public Tenant getTenantByKey(String key) {
        return tenantDao.findOneByKey(key);
    }

    public Tenant check(String type, String param) {
        return tenantDao.checkTenant(type, param);
    }

    public Map<String, Object> getTenantListByDataTable(HttpServletRequest request) {
        DataTableQuery dt = new DataTableQuery(request);
        List<Map<String, Object>> list = new ArrayList<>();

        String totalSql = "SELECT COUNT(1) FROM `siemens`.`tenant` WHERE 1=1 ";
        String sql = "Select * from `siemens`.`tenant` where 1=1";
        int total = jdbcTemplate.queryForList(totalSql).size();
        int filteredCount = total;
        if (!dt.getSearch().equals("")) {
            String search = " and (`tenant_name`like '%" + dt.getSearch() + "%' or `address` like '%" + dt.getSearch() + "%' or `contact` like '%" + dt.getSearch() + "%' or `telephone` like '%" + dt.getSearch() + "%' or `tenant_id` like '%" + dt.getSearch() + "%')";
            sql += search;
            filteredCount = jdbcTemplate.queryForList(totalSql + search).size();
        }

        if (!dt.getOrderDBColumn().equals("") && !dt.getOrderAscOrDesc().equals("")) {
            String order = " ORDER BY `" + dt.getOrderDBColumn() + "` " + dt.getOrderAscOrDesc();
            sql += order;
        }

        String limit = " limit " + dt.getStart() + "," + dt.getLength();
        sql += limit;

        list = jdbcTemplate.queryForList(sql);
        return dt.buildResponse(filteredCount, total, list);
//        return tenantDao.getTenants();
    }
}
